package com.lty.jeeg.server.modules.fas.service.impl;

import com.lty.jeeg.server.common.page.table.PageTableHandler;
import com.lty.jeeg.server.common.page.table.PageTableRequest;
import com.lty.jeeg.server.common.page.table.PageTableResponse;
import com.lty.jeeg.server.common.utils.BeanConverter;
import com.lty.jeeg.server.common.utils.UserUtil;
import com.lty.jeeg.server.modules.fas.dao.BorrowDao;
import com.lty.jeeg.server.modules.fas.dao.GoodsCategoryDao;
import com.lty.jeeg.server.modules.fas.dao.GoodsDao;
import com.lty.jeeg.server.modules.fas.dao.StockDao;
import com.lty.jeeg.server.modules.fas.dto.BorrowDTO;
import com.lty.jeeg.server.modules.fas.dto.GoodsCategoryDTO;
import com.lty.jeeg.server.modules.fas.dto.GoodsDTO;
import com.lty.jeeg.server.modules.fas.dto.StockDTO;
import com.lty.jeeg.server.modules.fas.model.Borrow;
import com.lty.jeeg.server.modules.fas.model.Stock;
import com.lty.jeeg.server.modules.fas.service.BorrowService;
import com.lty.jeeg.server.modules.sys.dao.DeptDao;
import com.lty.jeeg.server.modules.sys.dao.UserDao;
import com.lty.jeeg.server.modules.sys.model.Dept;
import com.lty.jeeg.server.modules.sys.model.User;
import com.lty.jeeg.server.modules.sys.service.UserService;
import com.lty.jeeg.server.modules.sys.service.impl.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * @author : xuchen
 * @date : 2019-03-02
 * Description : 借用
 */
@Service
@Slf4j
public class BorrowServiceImpl implements BorrowService {

    private final BorrowDao borrowDao;
    private final StockDao stockDao;
    private final UserDao userDao;
    private final GoodsDao goodsDao;
    private final GoodsCategoryDao goodsCategoryDao;
    private final DeptDao deptDao;


    @Autowired
    public BorrowServiceImpl(BorrowDao borrowDao, StockDao stockDao, UserDao userDao, GoodsDao goodsDao, GoodsCategoryDao goodsCategoryDao, DeptDao deptDao) {
        this.borrowDao = borrowDao;
        this.stockDao = stockDao;
        this.userDao = userDao;
        this.goodsDao = goodsDao;
        this.goodsCategoryDao = goodsCategoryDao;
        this.deptDao = deptDao;
    }

    @Override
    public BorrowDTO getById(Long id) {
        return borrowDao.getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(Long id) {
        log.debug("删除Borrow=>{}", id);
        return borrowDao.delete(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(BorrowDTO borrowDTO) {
        borrowDTO.preUpdate();
        log.debug("修改Borrow=>{}", borrowDTO.getId());
        return borrowDao.update(BeanConverter.map(borrowDTO, Borrow.class));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long save(BorrowDTO borrowDTO) {
        borrowDTO.preInsert();
        //生成编号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String date = sdf.format(new Date());
        String newName = "JY" + date + new Random().nextInt(10000);
        borrowDTO.setName(newName);
        //设置初始流程状态
        borrowDTO.setFlowState("0");
        Long id = borrowDao.save(BeanConverter.map(borrowDTO, Borrow.class));
        log.debug("新增Borrow=>{}",id);
        return id;
    }

    @Override
    public PageTableResponse list(PageTableRequest request) {
        request.getParams().put("dsf", BaseService.dataScopeFilter("fas", UserUtil.getCurrentUser(), "du1,du2", "ua1,ua2"));
        return new PageTableHandler(
                request1 -> borrowDao.count(request1.getParams()),
                request2 -> borrowDao.list(
                        request2.getParams(), request2.getOffset(), request2.getLimit()))
                .handle(request);
    }

    /**
     * 审核
     * @param id
     * @param flowState
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String approval(Long id, String flowState) {
        String msg = "操作成功";
        if(id != null && flowState != null){
            BorrowDTO borrowDTO = borrowDao.getById(id);//借用单
            Integer borrowerNum = borrowDTO.getBorrowerNum();//借用数量
            Long goodsId = borrowDTO.getGoodsId();//借用商品
            GoodsDTO goodsDTO = goodsDao.getById(goodsId);
            if("2".equals(flowState)){
                //确认借用修改库存
                //1出借方是个人扣减个人名下库存，出借方是部门扣减部门名下库存
                Long lenderPersonnel = borrowDTO.getLenderPersonnel();//出借方id
                Long lenderDepartment = borrowDTO.getLenderDepartment();//出借方部门id
                if(lenderPersonnel != null){
                    //出借方是 个人
                    User lender = userDao.getById(lenderPersonnel);
                    if(lender != null && lender.getId() != null){
                        Long stockId = stockDao.getIdByUserLib(goodsId, lender.getId(), lender.getDept().getId());
                        //修改个人名下库存
                        StockDTO stockDTO = new StockDTO();
                        if(stockId != null){
                            stockDTO = stockDao.getById(stockId);
                        }
                        if(stockDTO != null && stockDTO.getId() != null){
                            Integer totalNumber = stockDTO.getTotalNumber();
                            if(totalNumber >= borrowerNum){
                                stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"deduction"), Stock.class));
                            }else{
                                msg = "出借方人员名下该商品库存不足,无法借用";
                                return msg;
                            }
                        }else{
                            msg = "出借方人员名下没有该商品，请核对";
                            return msg;
                        }
                    }
                }else if(lenderDepartment != null){
                    //出借方是部门
                    Long stockId = stockDao.getIdByDeptLib(goodsId, lenderDepartment);
                    StockDTO stockDTO = new StockDTO();
                    if(stockId != null){
                        stockDTO = stockDao.getById(stockId);
                    }
                    if(stockDTO != null && stockDTO.getId() != null){
                        Integer totalNumber = stockDTO.getTotalNumber();
                        if(totalNumber >= borrowerNum){
                            //修改部门名下库存
                            stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"deduction"), Stock.class));
                        }else{
                            msg = "出借方部门名下该商品库存不足,无法借用";
                            return msg;
                        }
                    }else{
                        msg = "出借方部门名下没有该商品，无法借用";
                        return msg;
                    }
                }else{
                    msg = "请核对出借方人员和部门是否存在";
                    return msg;
                }

                Long borrowerPersonnel = borrowDTO.getBorrowerPersonnel();//借用方人员
                Long borrowerDepartment = borrowDTO.getBorrowerDepartment();//借用方部门
                //借用方是个人增加个人名下库存，借用方式部门增加部门名下库存
                if(borrowerPersonnel != null){
                    //借用方是个人
                    User borrower = userDao.getById(borrowerPersonnel);
                    if(borrower != null){
                        Long stockId = stockDao.getIdByUserLib(goodsId, borrower.getId(), borrower.getDept().getId());
                        StockDTO stockDTO = new StockDTO();
                        if(stockId != null){
                            stockDTO = stockDao.getById(stockId);
                        }
                        if(stockDTO != null && stockDTO.getId() != null){
                            //有当前商品库存(增加库存数量)
                            stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"increase"), Stock.class));

                        }else{
                            //没有当前商品库存，新增一条库存信息
                            Stock stock = new Stock();
                            stock.preInsert();
                            stock.setGoodsId(goodsId);//商品
                            Long goodsCategoryId = goodsDTO.getCategory();
                            GoodsCategoryDTO goodsCategoryDTO =goodsCategoryDao.getById(goodsCategoryId);
                            Long parentCategory = goodsCategoryDTO.getParentId();
                            stock.setParentCategory(parentCategory);//商品类型父级
                            stock.setCategory(goodsCategoryId);//商品类型
                            stock.setUserId(borrowerPersonnel);//所属人员
                            if(borrower.getDept() != null && borrower.getDept().getId() != null){
                                stock.setDeptId(borrower.getDept().getId());//所属部门
                                stock.setCompanyId(borrower.getDept().getCompany());//所属公司
                            }
                            stock.setTotalNumber(borrowerNum);//总数量
                            stock.setIdleNumber(0);//闲置数量
                            stockDao.save(stock);
                        }
                    }
                }else if(borrowerDepartment != null){
                    //借用方是部门
                    Long stockId = stockDao.getIdByDeptLib(goodsId, borrowerDepartment);
                    StockDTO stockDTO = new StockDTO();
                    if(stockId != null){
                        stockDTO = stockDao.getById(stockId);
                    }
                    if(stockDTO != null && stockDTO.getId() != null){
                        //增加库存数量
                        stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"increase"), Stock.class));
                    }else{
                        //新建库存记录
                        //没有当前商品库存，新增一条库存信息
                        Stock stock = new Stock();
                        stock.preInsert();
                        stock.setGoodsId(goodsId);//商品
                        Long goodsCategoryId = goodsDTO.getCategory();
                        GoodsCategoryDTO goodsCategoryDTO =goodsCategoryDao.getById(goodsCategoryId);
                        Long parentCategory = goodsCategoryDTO .getParentId();
                        stock.setParentCategory(parentCategory);//商品类型父级
                        stock.setCategory(goodsCategoryId);//商品类型
                        stock.setDeptId(borrowerDepartment);//所属部门
                        Dept borrowDept = deptDao.getById(borrowerDepartment);
                        if(borrowDept != null && borrowDept.getId() != null){
                            stock.setCompanyId(borrowDept.getCompany());//所属公司
                        }
                        stock.setTotalNumber(borrowerNum);//总数量
                        stock.setIdleNumber(0);//闲置数量
                        stockDao.save(stock);
                    }
                }else{
                    msg = "请核对借用方人员和部门是否存在";
                    return msg;
                }
            }
            //归还流程
            if("3".equals(flowState)){
                //归还时设置实际归还时间
                borrowDTO.setActualReturnTime(new Date());
                //归还库存
                //确认借用修改库存
                //1借用方方是个人扣减个人名下库存，借用方方是部门扣减部门名下库存
                Long borrowerPersonnel = borrowDTO.getBorrowerPersonnel();//借用方id
                Long borrowerDepartment = borrowDTO.getBorrowerDepartment();//借用方部门id
                if(borrowerPersonnel != null){
                    //借用方是 个人
                    User borrow = userDao.getById(borrowerPersonnel);
                    if(borrow != null && borrow.getId() != null){
                        Long stockId = stockDao.getIdByUserLib(goodsId, borrow.getId(), borrow.getDept().getId());
                        StockDTO stockDTO = new StockDTO();
                        if(stockId != null){
                            stockDTO = stockDao.getById(stockId);
                        }
                        //修改个人名下库存
                        if(stockDTO != null && stockDTO.getId() != null){
                            Integer totalNumber = stockDTO.getTotalNumber();
                            if(totalNumber >= borrowerNum){
                                stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"deduction"), Stock.class));
                            }else{
                                msg = "借用方人员名下该商品库存不足,无法归还";
                                return msg;
                            }
                        }else{
                            msg = "借用方人员名下没有该商品，无法归还";
                            return msg;
                        }
                    }
                }else if(borrowerDepartment != null){
                    //借用方是部门
                    Long stockId = stockDao.getIdByDeptLib(goodsId, borrowerDepartment);
                    StockDTO stockDTO = new StockDTO();
                    if(stockId != null){
                        stockDTO = stockDao.getById(stockId);
                    }
                    if(stockDTO != null && stockDTO.getId() != null){
                        Integer totalNumber = stockDTO.getTotalNumber();
                        if(totalNumber >= borrowerNum){
                            //修改部门名下库存
                            stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"deduction"), Stock.class));
                        }else{
                            msg = "出借方部门名下该商品库存不足,无法归还";
                            return msg;
                        }

                    }else{
                        msg = "借用方部门名下没有该商品，无法归还";
                        return msg;
                    }
                }else{
                    msg = "请核对借用方人员和部门是否存在";
                    return msg;
                }

                Long lenderPersonnel = borrowDTO.getLenderPersonnel();//出借方人员
                Long lenderDepartment = borrowDTO.getLenderDepartment();//出借方部门
                //出借方是个人增加个人名下库存，借用方式部门增加部门名下库存
                if(lenderPersonnel != null){
                    //出借方是个人
                    User lender = userDao.getById(lenderPersonnel);
                    if(lender != null){
                        Long stockId = stockDao.getIdByUserLib(goodsId, lender.getId(), lender.getDept().getId());
                        StockDTO stockDTO = new StockDTO();
                        if(stockId != null){
                            stockDTO = stockDao.getById(stockId);
                        }
                        if(stockDTO != null && stockDTO.getId() != null){
                            //有当前商品库存(增加库存数量)
                            stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"increase"), Stock.class));

                        }else{
                            //没有当前商品库存，新增一条库存信息
                            Stock stock = new Stock();
                            stock.preInsert();
                            stock.setGoodsId(goodsId);//商品
                            Long goodsCategoryId = goodsDTO.getCategory();
                            GoodsCategoryDTO goodsCategoryDTO =goodsCategoryDao.getById(goodsCategoryId);
                            Long parentCategory = goodsCategoryDTO .getParentId();
                            stock.setParentCategory(parentCategory);//商品类型父级
                            stock.setCategory(goodsCategoryId);//商品类型
                            stock.setUserId(lenderDepartment);//所属人员
                            if(lender.getDept() != null && lender.getDept().getId() != null){
                                stock.setDeptId(lender.getDept().getId());//所属部门
                                stock.setCompanyId(lender.getDept().getCompany());//所属公司
                            }
                            stock.setTotalNumber(borrowerNum);//总数量
                            stock.setIdleNumber(0);//闲置数量

                            stockDao.save(stock);
                        }
                    }
                }else if(lenderDepartment != null){
                    //出借方是部门
                    Long stockId = stockDao.getIdByDeptLib(goodsId, lenderDepartment);
                    StockDTO stockDTO = new StockDTO();
                    if(stockId != null){
                        stockDTO = stockDao.getById(stockId);
                    }
                    if(stockDTO != null && stockDTO.getId() != null){
                        //增加库存数量
                        stockDao.update(BeanConverter.map(modifyStock(stockDTO,borrowerNum,"increase"), Stock.class));
                    }else{
                        //新建库存记录
                        Stock stock = new Stock();
                        stock.preInsert();
                        stock.setGoodsId(goodsId);//商品
                        Long goodsCategoryId = goodsDTO.getCategory();
                        GoodsCategoryDTO goodsCategoryDTO =goodsCategoryDao.getById(goodsCategoryId);
                        Long parentCategory = goodsCategoryDTO.getParentId();
                        stock.setParentCategory(parentCategory);//商品类型父级
                        stock.setCategory(goodsCategoryId);//商品类型
                        stock.setDeptId(lenderDepartment);//所属部门
                        Dept lenderDept = deptDao.getById(lenderDepartment);
                        if(lenderDept != null && lenderDept.getId() != null){
                            stock.setCompanyId(lenderDept.getCompany());//所属公司
                        }
                        stock.setTotalNumber(borrowerNum);//总数量
                        stock.setIdleNumber(0);//闲置数量
                        stockDao.save(stock);
                    }
                }else{
                    msg = "请核对出借方人员和部门是否存在";
                    return msg;
                }
            }
            //修改借用单状态
            borrowDTO.setUpdateBy(UserUtil.getCurrentUser().getId());
            borrowDTO.setFlowState(flowState);
            borrowDao.update(BeanConverter.map(borrowDTO, Borrow.class));
        }
        return msg;
    }

    /**
     * 修改库存
     * @param stockDTO
     * @param deduction
     * @param type deduction:减库存;increase:加库存
     * @return
     */
    private static StockDTO modifyStock(StockDTO stockDTO, Integer deduction,String type){
        if("deduction".equals(type)){
            Integer idleNumber = stockDTO.getIdleNumber();//闲置库存
            Integer totalNumber = stockDTO.getTotalNumber();//总库存
            Integer num = idleNumber - deduction;
            if(num <= 0){
                num = 0;
            }
            stockDTO.setIdleNumber(num);
            stockDTO.setTotalNumber(totalNumber - deduction);
            if(totalNumber - deduction == 0){//库存为0删除
                stockDTO.setIsDeleted(1);
            }
        }
        if("increase".equals(type)){
            stockDTO.setTotalNumber(stockDTO.getTotalNumber() + deduction);
        }

        return stockDTO;

    }
}
